package com.dreamwhale.machinery.pay.ali.server.Impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.dreamwhale.machinery.adviceException.DragonException;
import com.dreamwhale.machinery.config.DataResult;
import com.dreamwhale.machinery.dao.DictDetailMapper;
import com.dreamwhale.machinery.dao.UserApplyMapper;
import com.dreamwhale.machinery.dao.VipUserInfoMapper;
import com.dreamwhale.machinery.entity.DictDetail;
import com.dreamwhale.machinery.entity.UserApply;
import com.dreamwhale.machinery.entity.VipUserInfo;
import com.dreamwhale.machinery.goods.entity.YxStoreOrder;
import com.dreamwhale.machinery.goods.mapper.YxStoreOrderMapper;
import com.dreamwhale.machinery.pay.ali.config.ALiPayConfig;
import com.dreamwhale.machinery.pay.ali.config.AliConfig;
import com.dreamwhale.machinery.pay.ali.server.AliPayService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@Service
public class AliPayServiceImpl implements AliPayService {
    @Resource
    private YxStoreOrderMapper yxStoreOrderMapper;

    @Resource
    private ALiPayConfig aLiPayConfig;

    @Resource
    private AlipayClient alipayClient;

    @Resource
    private UserApplyMapper userApplyMapper;

    @Resource
    private VipUserInfoMapper vipUserInfoMapper;

    @Resource
    private DictDetailMapper dictDetailMapper;

    @Override
    public String orderPay(String orderId, String body, BigDecimal money, String backJsonInfo) throws AlipayApiException {

        AlipayTradeAppPayModel alipayTradeAppPayModel = new AlipayTradeAppPayModel();
        alipayTradeAppPayModel.setBody(body);
        alipayTradeAppPayModel.setOutTradeNo(orderId);

        System.out.println(money.toString());
        alipayTradeAppPayModel.setTotalAmount(money.toString());
        alipayTradeAppPayModel.setProductCode("QUICK_MSECURITY_PAY");
        alipayTradeAppPayModel.setTimeoutExpress("30m");
        alipayTradeAppPayModel.setSubject("机械之都支付");
        alipayTradeAppPayModel.setPassbackParams(backJsonInfo);
        AlipayTradeAppPayRequest alipayTradeAppPayRequest = new AlipayTradeAppPayRequest();
        alipayTradeAppPayRequest.setBizModel(alipayTradeAppPayModel);
        alipayTradeAppPayRequest.setNotifyUrl(aLiPayConfig.getNotifyUrl());
        AlipayTradeAppPayResponse alipayTradeAppPayResponse = alipayClient.sdkExecute(alipayTradeAppPayRequest);
        alipayTradeAppPayResponse.setOutTradeNo(orderId);
        return alipayTradeAppPayResponse.getBody();
    }

    @Override
    public DataResult orderApply(String orderId, Integer userId, Integer pid) {
        try {
            UserApply userApply = userApplyMapper.selectById(orderId);
            HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
            objectObjectHashMap.put("payType", 3);
            objectObjectHashMap.put("userId", userId);
            objectObjectHashMap.put("pid", pid);
            String aliPayInfo = orderPay(userApply.getApplyOrderId(), "", userApply.getApplyMoney(), JSON.toJSONString(objectObjectHashMap));
            return new DataResult(aliPayInfo);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return DataResult.build(500, "支付宝支付出错");
        }
    }

    @Override
    public DataResult order(String orderId, Integer userId) {
        try {
            YxStoreOrder yxStoreOrder = yxStoreOrderMapper.selectById(orderId);
            HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
            objectObjectHashMap.put("payType", 1);
            objectObjectHashMap.put("userId", userId);
            String aliPayInfo = orderPay(yxStoreOrder.getOrderId().toString(), "", yxStoreOrder.getTotalPrice(), JSON.toJSONString(objectObjectHashMap));
            return new DataResult(aliPayInfo);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return DataResult.build(500, "支付宝支付出错");
        }
    }

    @Override
    public DataResult recharge(BigDecimal money, Integer userId) {
        try {
            HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
            objectObjectHashMap.put("payType", 0);
            objectObjectHashMap.put("userId", userId);
            String aliPayInfo = orderPay(IdWorker.getIdStr(), "", money, JSON.toJSONString(objectObjectHashMap));
            return new DataResult(aliPayInfo);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return DataResult.build(500, "支付宝支付出错");
        }
    }

    @Override
    public String notify(HttpServletRequest request, HttpServletResponse response) {

        if (rsaCheckV1(request)) {
            String tradeStatus = request.getParameter("trade_status");
            String outTradeNo = request.getParameter("out_trade_no");
            String trade_no = request.getParameter("trade_no");
            String passbackParams = request.getParameter("passback_params");
            String totalAmount = request.getParameter("total_amount");
            JSONObject jsonObject = JSON.parseObject(passbackParams);
            String userId = jsonObject.get("userId").toString();
            String payType = jsonObject.get("payType").toString();
            Integer uid = Integer.parseInt(userId);
            BigDecimal bigDecimal = BigDecimal.valueOf(Double.parseDouble(totalAmount));

            //TODO:处理回调信息
            switch (Integer.parseInt(payType)) {
                case 0://充值

                    System.out.println("充值信息");
                    break;
                case 1://
                    YxStoreOrder yxStoreOrder = yxStoreOrderMapper.selectOne(new QueryWrapper<YxStoreOrder>().eq("order_id", outTradeNo));
                    yxStoreOrder.setPaid(true);
                    yxStoreOrder.setPayTime(LocalDateTime.now());
                    yxStoreOrderMapper.updateById(yxStoreOrder);
                    System.out.println("订单信息");
                    break;
                case 2://报名
                    UserApply applyOrder = userApplyMapper.selectById(new QueryWrapper<UserApply>().eq("apply_order_id", outTradeNo));
                    applyOrder.setApplyPayTime(LocalDateTime.now());
                    userApplyMapper.updateById(applyOrder);
                    Object pid1 = jsonObject.get("pid");
                    //给邀请的人一个奖励
                    if (pid1 != null) {
                        DictDetail dictDetail = dictDetailMapper.selectOne(new QueryWrapper<DictDetail>().eq("label", "applyAwards"));
                        BigDecimal decimal = BigDecimal.valueOf(Integer.parseInt(dictDetail.getValue()));
                        Integer pid = Integer.parseInt(pid1.toString());
                        VipUserInfo userInfo = vipUserInfoMapper.selectById(pid);
                        userInfo.setPayMoney(userInfo.getPayMoney().add(decimal));
                        vipUserInfoMapper.updateById(userInfo);
                    }
                    break;
                case 3:

                    VipUserInfo vipUserInfo = vipUserInfoMapper.selectById(outTradeNo);
                    vipUserInfo.setPayTime(LocalDateTime.now());
                    vipUserInfoMapper.updateById(vipUserInfo);


                    break;

                default:
                    break;
            }

            return "success";
        }

        return "fail";
    }

    @Override
    public Boolean rsaCheckV1(HttpServletRequest request) {
        try {
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                String[] values = requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++)
                    valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
                params.put(name, valueStr);
            }
            return AlipaySignature.rsaCheckV1(params, AliConfig.private_key, AliConfig.input_charset, AliConfig.pay_sign_type);
        } catch (AlipayApiException e) {
            return false;
        }
    }

    @Override
    public DataResult refund(String orderId, String reason) {
        if (StringUtils.isBlank(orderId)) throw new DragonException("订单号不正确");
        YxStoreOrder yxStoreOrder = yxStoreOrderMapper.selectOne(new QueryWrapper<YxStoreOrder>().eq("order_id", orderId));
        if (yxStoreOrder == null) throw new DragonException("无此订单信息");
        double v = yxStoreOrder.getTotalPrice().doubleValue();
        if (v <= 0) throw new DragonException("金额必须大于0");
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
        // 商户订单号
        model.setOutTradeNo(orderId);
        // 退款金额
        model.setRefundAmount(String.valueOf(v));
        // 退款原因
        model.setRefundReason(reason);
        // 退款订单号(同一个订单可以分多次部分退款，当分多次时必传)
        // model.setOutRequestNo(UUID.randomUUID().toString());
        AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();
        alipayRequest.setBizModel(model);
        AlipayTradeRefundResponse alipayResponse = null;
        try {
            alipayResponse = alipayClient.execute(alipayRequest);
            System.out.println(alipayResponse);
        } catch (AlipayApiException e) {
            return new DataResult(300, "退款成功", null);
        }
        if (alipayResponse != null) {
            String code = alipayResponse.getCode();
            String subCode = alipayResponse.getSubCode();
            String subMsg = alipayResponse.getSubMsg();
            if ("10000".equals(code)
                    && StringUtils.isBlank(subCode)
                    && StringUtils.isBlank(subMsg)) {
                // 表示退款申请接受成功，结果通过退款查询接口查询
                // 修改用户订单状态为退款
                return new DataResult(200, "退款成功", null);
            }
            return new DataResult(200, subMsg, null);
        }
        return new DataResult(200, "退款失败", null);
    }

    @Override
    public DataResult vipRecharge(String payOrderId, Integer userId) {
        try {
            VipUserInfo vipUserInfo = vipUserInfoMapper.selectById(payOrderId);
            HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
            objectObjectHashMap.put("payType", 3);
            objectObjectHashMap.put("userId", userId);
            String aliPayInfo = orderPay(vipUserInfo.getPayOrderId(), "", vipUserInfo.getPayMoney(), JSON.toJSONString(objectObjectHashMap));
            return new DataResult(aliPayInfo);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return DataResult.build(500, "支付宝支付出错");
        }
    }
}
